from datetime import datetime

from django.db import transaction
from django_redis import get_redis_connection
from rest_framework import serializers

from goods.models import SKU
from users.models import Address
from orders.models import OrderInfo, OrderGoods


class SaveOrderSerializer(serializers.Serializer):
    address = serializers.IntegerField(write_only=True)
    pay_method = serializers.IntegerField(write_only=True)
    order_id = serializers.CharField(read_only=True)

    def validate_pay_method(self, value):
        if value not in [1, 2]:
            raise serializers.ValidationError('支付方式错误')
        return value

    def validate_address(self, value):
        count = Address.objects.filter(pk=value).count()
        if count <= 0:
            raise serializers.ValidationError('收货地址不存在')
        return value

    def create(self, validated_data):
        with transaction.atomic():
            sid = transaction.savepoint()
            # 获取校验后的数据
            address = validated_data.get('address')
            pay_method = validated_data.get('pay_method')

            user_id = self.context['request'].user.id

            order_id = datetime.now().strftime('%Y%m%d%H%M%S') + '%09d' % user_id

            total_count = 0
            total_amount = 0

            # 1.创建订单对象
            order = OrderInfo.objects.create(
                order_id=order_id,
                user_id=user_id,
                address_id=address,
                total_count=0,
                total_amount=0,
                freight=10,
                pay_method=pay_method

            )
            # 2.查询redis勾选商品
            redis_cli = get_redis_connection('cart')
            cart_key = 'cart_%d' % user_id
            cart_select_key = 'cart_select_%d' % user_id
            cart_dict = redis_cli.hgetall(cart_key)
            cart_dict2 = {}
            for sku_id, count in cart_dict.items():
                cart_dict2[int(sku_id)] = int(count)

            sku_ids = redis_cli.smembers(cart_select_key)
            sku_ids2 = [int(sku_id) for sku_id in sku_ids]

            # 3.查询所有商品
            skus = SKU.objects.filter(pk__in=sku_ids2)

            # 4.遍历商品
            for sku in skus:
                # 获取购买数量
                count = cart_dict2[sku.id]
                # 4.1 判断库存
                if sku.stock < count:
                    # 错误回滚
                    transaction.savepoint_rollback(sid)
                    raise serializers.ValidationError('库存不足')
                # # 4.2 修改库存
                # sku.stock -= count
                # # 4.3 修改销量
                # sku.sales += count
                # # 保存修改
                # sku.save()

                # 使用乐观锁
                stock = sku.stock - count
                sales = sku.sales + count

                result = SKU.objects.filter(pk=sku.id, stock=sku.stock).update(stock=stock, sales=sales)

                if result <= 0:
                    transaction.savepoint_rollback(sid)
                    raise serializers.ValidationError('库存不足')

                # 4.4 创建订单商品对象
                OrderGoods.objects.create(
                    order_id=order_id,
                    sku_id=sku.id,
                    count=count,
                    price=sku.price
                )
                # 4.5.计算总件数，总金额
                total_count += count
                total_amount += count * sku.price

            # 5 修改总件数，总金额
            order.total_count = total_count
            order.total_amount = total_amount
            order.save()
            # 提交事务
            transaction.savepoint_commit(sid)

            # 6.删除redis里面的商品id
            redis_cli.hdel(cart_key, *sku_ids2)
            redis_cli.srem(cart_select_key, *sku_ids2)


            return order
